//------------------------------------------------------------------------------
//!	@file XpanderSysEx.h
//!	@brief
//!		Oberheim Xpander System Exclusive Format
//!
//!	$Id: $
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	Copyright and Disclaimer Notice
//
//	Copyright (c) 2013 A.C. Verbeck
//	original author: Greg Baumont - http://greg-baumont.com
//
//	This file is part of XSPV: Oberheim Xpander Single Patch Viewer.
//
//	XSPV is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	XSPV is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with XSPV.  If not, see <http://www.gnu.org/licenses/>.
//
//------------------------------------------------------------------------------
#pragma once

//------------------------------------------------------------------------------
// Modulation Flags
//------------------------------------------------------------------------------
typedef enum _ModulationFlags {
	MODFLAG_KEYBD	= 0x01,
	MODFLAG_LAG		= 0x02,
	MODFLAG_LEV_1	= 0x04,
	MODFLAG_VIB		= 0x08
} ModulationFlags;

//------------------------------------------------------------------------------
// VCO Wave Flags
//------------------------------------------------------------------------------
typedef enum _VCOWaveFlags {
	VCOWAVEFLAG_TRI		= 0x01,
	VCOWAVEFLAG_SAW		= 0x02,
	VCOWAVEFLAG_PULSE	= 0x04,
	VCOWAVEFLAG_SYNC	= 0x08,
	VCOWAVEFLAG_NOISE	= 0x10
} VCOWaveFlags;

//------------------------------------------------------------------------------
// VCF Filter Types
//------------------------------------------------------------------------------
typedef enum _VCFFilterTypes {
	VCFFILTER_LOW_1, VCFFILTER_LOW_2, VCFFILTER_LOW_3, VCFFILTER_LOW_4,
	VCFFILTER_HIGH_1, VCFFILTER_HIGH_2, VCFFILTER_HIGH_3,
	VCFFILTER_BAND_2, VCFFILTER_BAND_4,
	VCFFILTER_NOTCH_2,
	VCFFILTER_PHASE_3,
	VCFFILTER_HIGH_2L, VCFFILTER_HIGH_3L,
	VCFFILTER_NOTCH_2L,
	VCFFILTER_PHASE_3L
} VCFFilterTypes;

//------------------------------------------------------------------------------
// FM Destination Types
//------------------------------------------------------------------------------
typedef enum _FMDestinationTypes {
	FMDEST_VCO,
	FMDESTFM_VCF
} FMDestinationTypes;

//------------------------------------------------------------------------------
// Modulation Sources Flags
//------------------------------------------------------------------------------
typedef enum _ModulationSourcesFlags {
	MODSRC_KBD, MODSRC_LAG, MODSRC_VEL, MODSRC_RVEL, MODSRC_PRES,
	MODSRC_TRK1, MODSRC_TRK2, MODSRC_TRK3,
	MODSRC_RMP1, MODSRC_RMP2, MODSRC_RMP3, MODSRC_RMP4,
	MODSRC_ENV1, MODSRC_ENV2, MODSRC_ENV3, MODSRC_ENV4, MODSRC_ENV5,
	MODSRC_PED1, MODSRC_PED2,
	MODSRC_LFO1, MODSRC_LFO2, MODSRC_LFO3, MODSRC_LFO4, MODSRC_LFO5,
	MODSRC_VIB, MODSRC_LEV1, MODSRC_LEV2
} ModulationSourcesFlags;

//------------------------------------------------------------------------------
// Lag Mode Flags
//------------------------------------------------------------------------------
typedef enum _LagModeFlags {
	LAGMODE_LEGATO		= 0x01,
	LAGMODE_EXPO		= 0x02,
	LAGMODE_EQUAL_TIME	= 0x04
} LagModeFlags;

//------------------------------------------------------------------------------
// Trigger Types
//------------------------------------------------------------------------------
typedef enum _TriggerTypes {
	TRIGGER_OFF,
	TRIGGER_SINGLE,
	TRIGGER_MULTI,
	TRIGGER_EXTRIG
} TriggerTypes;

//------------------------------------------------------------------------------
// Wave Types
//------------------------------------------------------------------------------
typedef enum _WaveTypes {
	WAVET_TRIANGLE, WAVET_UP_SAW, WAVET_DOWN_SAW, WAVET_SQUARE,
	WAVET_RANDOM, WAVET_NOISE, WAVET_SAMPLE
} WaveTypes;

//------------------------------------------------------------------------------
// Lag Flags (bitfield)
//------------------------------------------------------------------------------
typedef enum _LagFlags {
	LAGF_LAG = 0x01
} LagFlags;

//------------------------------------------------------------------------------
// Envelope Mode Flags (bitfield)
//------------------------------------------------------------------------------
typedef enum _EnvelopeModeFlags {
	ENVMODE_RESET			= 0x01,
	ENVMODE_INVALID_VALUE	= 0x02,		// original MIDI SPEC did not mention this unused bit
	ENVMODE_MULTI			= 0x04,		// SINGLE if not MULTI
	ENVMODE_GATED			= 0x08,
	ENVMODE_EXTRIG			= 0x10,
	ENVMODE_LFOTRIG			= 0x20,
	ENVMODE_DADR			= 0x40,
	ENVMODE_FREERUN			= 0x80
} EnvelopeModeFlags;

//------------------------------------------------------------------------------
// LFO Trigger Codes
//------------------------------------------------------------------------------
typedef enum _LFOTriggerCodes {
	LFOTRIG_LFO1,
	LFOTRIG_LFO2,
	LFOTRIG_LFO3,
	LFOTRIG_LFO4,
	LFOTRIG_LFO5,
	LFOTRIG_VIB
} LFOTriggerCodes;

//------------------------------------------------------------------------------
// Ramp Flags (bitfield)
//------------------------------------------------------------------------------
typedef enum _RampFlags {
	RAMPF_GATED		= 0x01,
	RAMPF_LFOTRIG	= 0x02,
	RAMPF_EXTRIG	= 0x04,
	RAMPF_MULTI		= 0x08		// SINGLE if not MULTI
} RampFlags;

//------------------------------------------------------------------------------
// Modulation Destination Types
//------------------------------------------------------------------------------
typedef enum _ModulationDestinationTypes {
	VCO1_FRQ, VCO1_PW, VCO1_VOL,
	VCO2_FRQ, VCO2_PW, VCO2_VOL,
	VCF_FRQ, VCF_RES, VCA1_VOL, VCA2_VOL,
	LFO1_SPD, LFO1_AMP,
	LFO2_SPD, LFO2_AMP,
	LFO3_SPD, LFO3_AMP,
	LFO4_SPD, LFO4_AMP,
	LFO5_SPD, LFO5_AMP,
	ENV1_DLY, ENV1_ATK, ENV1_DCY, ENV1_REL, ENV1_AMP,
	ENV2_DLY, ENV2_ATK, ENV2_DCY, ENV2_REL, ENV2_AMP,
	ENV3_DLY, ENV3_ATK, ENV3_DCY, ENV3_REL, ENV3_AMP,
	ENV4_DLY, ENV4_ATK, ENV4_DCY, ENV4_REL, ENV4_AMP,
	ENV5_DLY, ENV5_ATK, ENV5_DCY, ENV5_REL, ENV5_AMP,
	FM_AMP,LAG_SPD
} ModulationDestinationTypes;

//------------------------------------------------------------------------------
// Single patch STRUCT
//------------------------------------------------------------------------------
typedef struct _SinglePatch {
//VCO
	struct vco {
		unsigned char freq;			/* Frequency */
		char detune;				/* Detune*/
		unsigned char pw;			/* Pulse Width*/
		unsigned char vol;			/* Volume*/
		unsigned char mod;			/* Standard Modulation flags */
		unsigned char wave;			/* VCO Wave Shape flags */
	} vco[2];

// VCF
	struct vcf {
		unsigned char freq;			/* Frequency */
		unsigned char res;			/* Resonance */
		unsigned char fmode;		/* Filter Mode Code */
		unsigned char vca1;	 		/* VCA 1 level*/
		unsigned char vca2;	 		/* VCA 2 level*/
		unsigned char mod;			/* Standard Modulation flags */
	} vcf;

//FM LAG
	struct fm_lag {
		unsigned char fm_amp;	 	/* FM Amplitude */
		unsigned char fm_dest;	 	/* FM destination code*/
		unsigned char lag_in;	 	/* Lag Input code */
		unsigned char lag_rate;	 	/* Lag Rate */
		unsigned char lag_mode; 	/* Lag Mode */
	} fm_lag;

//LFO (x5)
	struct lfo {
		unsigned char speed;		/* LFO Speed*/
		unsigned char retrig_mode;	/* Retrigger mode */
		unsigned char lag;			/* Lag flag*/
		unsigned char wave;			/* Wave Shape code */
		unsigned char retrig;		/* Retrigger Point */
		unsigned char sample;		/* LFO Sample Source */
		unsigned char amp;			/* LFO Amplitude */
	} lfo[5];

//ENV (x5)
	struct env {
		unsigned char flags;		/* Miscellaneous flags */
		unsigned char lfotrig;		/* Triggering LFO code */
		unsigned char delay;		/* Delay Time*/
		unsigned char attack;		/* Attack Time*/
		unsigned char decay;		/* Decay Time*/
		unsigned char sustain;		/* Sustain Level*/
		unsigned char release;		/* Release Time */
		unsigned char amp;			/* Envelope Amplitude */
	} env[5];

// TRACK (x3)
	struct track {
		unsigned char input;		/* Tracking Generator Source */
		unsigned char point[5];		/* Mapped vals for Input Pts*/
	} track[3];

// RAMP (x4)
	struct ramp {
		unsigned char rate; 		/* Ramp Time*/
		unsigned char flags;		/* Miscellaneous flags */
		unsigned char lfotrig;		/* LFO Trigger Code*/
	} ramp[4];

//MOD MATRIX (x20)
	struct mod {
		unsigned char source;		/* Modulation Source code*/
		char amount;				/* Modulation Amount */
		unsigned char dest;			/* Modulation Destination*/
	} mod[20];

//NAME
	struct name {
		wchar_t character[8+1]; 	/*Name*/
	} name;

} SinglePatch;

//------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------
bool LocateSinglePatchData(FILE* pFile);
void ReadSinglePatchData(FILE* pFile, SinglePatch* pPatch);
void DumpPatch(const SinglePatch* pPatch);

//
//	End: XpanderSysEx.h
//